package com.dong.mjblog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dong.mjblog.dto.CommentListDTO;
import com.dong.mjblog.entity.CommentEntity;
import com.dong.mjblog.entity.QuestionEntity;
import com.dong.mjblog.entity.UserEntity;
import com.dong.mjblog.enums.CommentTypeEnum;
import com.dong.mjblog.exception.CustomizeErrorCode;
import com.dong.mjblog.exception.CustomizeException;
import com.dong.mjblog.mapper.CommentMapper;
import com.dong.mjblog.mapper.QuestionMapper;
import com.dong.mjblog.mapper.UserMapper;
import com.dong.mjblog.service.CommentService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author:dxf
 * @Date:2020/10/5-10-05 11:25
 */
@Service
public class CommentImpl extends ServiceImpl<CommentMapper, CommentEntity> implements CommentService {

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private UserMapper userMapper;

    @Transactional
    public void comment(CommentEntity commentEntity) {
        if (commentEntity.getType() == CommentTypeEnum.COMMENT.getType()) {
            //回复评论
            CommentEntity comment = getById(commentEntity.getParentId());
            if (comment == null) {
                throw new CustomizeException(CustomizeErrorCode.COMMENT_NOT_FOUND);
            }
            save(commentEntity);
        } else {
            //回复问题
            QuestionEntity question = questionMapper.selectById(commentEntity.getParentId());
            if (question == null) {
                throw new CustomizeException(CustomizeErrorCode.QUESTION_NOT_FOUND);
            }
            save(commentEntity);
            question.setCommentCount(1L);
            questionMapper.incCommentCount(question);
        }
    }

    public List<CommentListDTO> listByTargetId(Long id, CommentTypeEnum type) {
        //评论列表
        QueryWrapper<CommentEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", id)
                .eq("type", type.getType())
                .orderByDesc("gmt_modified");

        List<CommentEntity> commentEntities = list(queryWrapper);
        if (commentEntities.size() == 0) {
            return new ArrayList<>();
        }

        //找到所有的用户id
        Set<Long> userIds = commentEntities.stream().map(CommentEntity::getCommentator).collect(Collectors.toSet());
        QueryWrapper<UserEntity> userWrapper = new QueryWrapper<>();
        userWrapper.in("id", userIds);
        //找到所有的用户
        List<UserEntity> userEntities = userMapper.selectList(userWrapper);

        //如果是for循环评论，再循环用户进行比对，就是n的平方次，效率不高，因此采用类似的stream map方式 key(id)=>value(userEntity)
        Map<Long, UserEntity> userMap = userEntities.stream().collect(Collectors.toMap(UserEntity::getId, userEntity -> userEntity));

        //转换commentEntity为commentDTO
        List<CommentListDTO> commentListDTOS = commentEntities.stream().map(commentEntity -> {
            CommentListDTO commentListDTO = new CommentListDTO();
            BeanUtils.copyProperties(commentEntity, commentListDTO);
            commentListDTO.setUser(userMap.get(commentEntity.getCommentator()));
            String date = timeStamp2Date(commentEntity.getGmtModified().toString(),"");
            commentListDTO.setGmtModified(date);
            return commentListDTO;
        }).collect(Collectors.toList());
        return commentListDTOS;
    }


    /**
     * 时间戳转换成日期格式字符串
     *
     * @param seconds
     * @param format
     * @return
     */
    public static String timeStamp2Date(String seconds, String format) {
        if (seconds == null || seconds.isEmpty() || seconds.equals("null")) {
            return "";
        }
        if (format == null || format.isEmpty()) {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date(Long.parseLong(seconds + "000")));
    }
}